package com.protobuf;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.protobuf.model.UserProto;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * This example demonstrates serving up REST payloads encoded using
 * <a href="https://developers.google.com/protocol-buffers/">Google Protocol
 * Buffers</a>.
 */
@SpringBootApplication
public class ProtoServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ProtoServerApplication.class, args);
	}

	@Bean
	ProtobufHttpMessageConverter protobufHttpMessageConverter() {
		return new ProtobufHttpMessageConverter();
	}

	private UserProto.User user(long id, String name, Collection<String> phones) {
		
		Collection<UserProto.User.PhoneNumber> pnList = 
		phones.stream() .map
		( e -> 
			UserProto.User.PhoneNumber.newBuilder().setNumber(e).build()
		).collect(Collectors.toList());
		
		
		return UserProto.User.newBuilder().setId(id).setName(name).addAllPhone(pnList).build();
	}

	@Bean
	UserRepository userRepository() {
		Map<Long, UserProto.User> userM = new ConcurrentHashMap<Long, UserProto.User>();
		
		Arrays.asList
		(
				user(1, "Chris", Arrays.asList("1566666", "15777777")),
				user(2, "Josh", Arrays.asList("157777777777", "158888888888")),
				user(3, "Matt", Arrays.asList("1566666", "159999999999999")),
				user(4, "Russ", Arrays.asList("1599999999", "15733337")),
				user(5, "fffff", Arrays.asList("1111111112121", "12121212"))
		)
		.forEach(c -> userM.put(c.getId(), c));
		// UserRepository 只有一个抽象方法，可以认为是一个函数接口，所以可以用lambda表达式 表示。
		
		return userM::get;
	}
}

interface UserRepository {
	UserProto.User findById(long id);
}
@RestController
class UserRestController {
	@Autowired
	private UserRepository userRepository;

	@RequestMapping("/user/{id}")
	UserProto.User user(@PathVariable Integer id) {
		return userRepository.findById(id);
	}

	@RequestMapping("/map/{id}")
	Map<String, String> map(@PathVariable Integer id) {
		Map<String, String> m = new HashMap<String, String>();
		m.put("name", "yonyou");
		m.put("www", "yonyou.com");
		return m;
	}

}